package com.baitiaojun.video.support;

import com.alibaba.fastjson.JSONObject;
import com.baitiaojun.api.util.ConstantUtil;
import com.baitiaojun.api.util.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @类名 BaiduUtil
 * @描述 TODO
 * @作者 白条君
 * @创建日期 2023/1/9 23:07
 * @版本 1.0
 */
@Slf4j
@Component
public class PortraitSegmentationSupport {

    @Value("${baidu.authHost}")
    private String authHost;

    @Value("${baidu.ak}")
    private String ak;

    @Value("${baidu.sk}")
    private String sk;

    @Value("${baidu.url}")
    private String url;

    @Autowired
    private RedisSupport redisSupport;

    /**
     * 进行人像分割
     */
    public String bodySeg(InputStream ins) throws Exception {
        String base64Image = convertFileToBase64(ins);
        //获取accesstoken
        String accessTokenKey = ConstantUtil.BAIDU_ACCESS_TOKEN;
        Object accessToken = redisSupport.getValue(accessTokenKey);
        if (ObjectUtils.isEmpty(accessToken)) {
            accessToken = this.getAccessToken();
            redisSupport.setValue(accessTokenKey, accessToken, 1, TimeUnit.DAYS);
        }
        //创建map对象封装image为key的请求参数，value是base64的字符串
        Map<String, Object> param = new HashMap<>();
        param.put("image", base64Image);
        //定义请求获取人像分割图片的url
        String urlStr = url + "?access_token=" + accessToken;
        //获取结果
        HttpUtil.HttpResponse res = HttpUtil.postUrlEncoded(urlStr, param);
        return res.getBody();
    }

    public BufferedImage resize(BufferedImage img, int newW, int newH) {
        Image tmp = img.getScaledInstance(newW, newH, Image.SCALE_SMOOTH);
        BufferedImage dimg = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = dimg.createGraphics();
        g2d.drawImage(tmp, 0, 0, null);
        g2d.dispose();
        return dimg;
    }

    public BufferedImage convert(String labelmapBase64, int realWidth, int realHeight) {
        BufferedImage grayImage = null;
        try {
            byte[] bytes = Base64.getDecoder().decode(labelmapBase64);
            InputStream is = new ByteArrayInputStream(bytes);
            BufferedImage image = ImageIO.read(is);
            BufferedImage newImage = this.resize(image, realWidth, realHeight);
            grayImage = new BufferedImage(realWidth, realHeight, BufferedImage.TYPE_BYTE_GRAY);
            for(int i= 0 ; i < realWidth ; i++){
                for(int j = 0 ; j < realHeight; j++){
                    int rgb = newImage.getRGB(i, j);
                    grayImage.setRGB(i, j, rgb * 255);  //将像素存入缓冲区
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return grayImage;
    }

    public String convertFileToBase64(InputStream ins) {
        byte[] buffer = null;
        try {
            buffer = new byte[ins.available()];
            ins.read(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ObjectUtils.isNotEmpty(ins)) {
                try {
                    ins.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        // 对字节数组进行Base64编码，得到Base64编码的字符串
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(buffer);
    }

    public String getAccessToken() {
        // 获取token地址
        // grant_type为固定参数
        String getAccessTokenUrl = this.authHost + "?grant_type=client_credentials" + "&client_id=" + this.ak + "&client_secret=" + this.sk;
        try {
            URL realUrl = new URL(getAccessTokenUrl);
            // 打开和URL之间的连接
            HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.err.println(key + "--->" + map.get(key));
            }
            // 定义BufferedReader输入流来读取URL的响应
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuilder result = new StringBuilder();
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            /**
             * 返回结果示例
             */
            log.info("result:" + result);
            JSONObject jsonObject = JSONObject.parseObject(result.toString());
            return jsonObject.getString("access_token");
        } catch (Exception e) {
            log.warn("获取token失败！");
            e.printStackTrace(System.err);
        }
        return null;
    }
}
